package com.cctc.juc.source.Athread.threadpool;

import java.util.List;
import java.util.concurrent.*;

/**
 * [ForkJoinPool（并行任务）线程池] 实现类。
 * 描述信息：
 * ForkJoinPool 与其他类型的 ExecutorService 的不同之处主要在于采用了 “工作窃取”：
 * - 池中的所有线程都试图查找并执行提交到池中的任务和 / 或由其他活动任务创建的任务（如果不存在，最终会阻止等待工作）。
 * 当大多数任务生成其他子任务时（就像大多数 ForkJoinTasks 一样），以及当许多小任务从外部客户端提交到池中时，这可以实现高效的处理。
 * - 特别是在构造函数中将 asyncMode 设置为 true 的时候。
 * 对于需要单独或自定义池的应用程序，可以使用给定的目标并行级别构建 ForkJoinPool；默认情况下等于可用处理器的数量。
 * - 池试图通过动态添加、挂起或恢复内部工作线程来维护足够的活动（或可用）线程，即使某些任务在等待加入其他任务时停滞不前。
 * - 但是，在 I/O 受阻或其他非托管同步的情况下，无法保证进行此类调整。
 * 除了执行和生命周期控制方法外，此类还提供了状态检查方法（例如getStealCount），旨在帮助开发、调优和监控 fork/join 应用程序。
 * 此外，toString() 方法以一种方便的形式返回池状态的指示，以便进行非正式监控。
 */
public class EForkJoinPool extends AbstractExecutorService {

    /**
     * [核心] 构造器
     *
     * @param parallelism 并行级别，对应于主动参与或可参与任务处理的线程的最大数量，默认情况下等于可用处理器的数量；
     * @param factory     创建 Worker 工作线程的工厂，默认为 DefaultForkJoinWorkerThreadFactory；
     * @param handler     新任务拒绝策略，默认为 AbortPolicy（直接拒绝，并抛出异常）
     * @param asyncMode   是否开启并行模式？如果为 true，则为并行 “ForkJoinTask” 分别建立 FIFO_QUQUE 或 LIFO_QUEUE 工作队列。
     */
    public EForkJoinPool(int parallelism,
                         ForkJoinWorkerThreadFactory factory,
                         UncaughtExceptionHandler handler,
                         boolean asyncMode) {
        this(checkParallelism(parallelism),
                checkFactory(factory),
                handler,
                asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
                "ForkJoinPool-" + nextPoolId() + "-worker-");
        checkPermission();
    }

    @Override
    public void execute(Runnable task) {
        // 1. 提交新任务，无返回值，无法抛出异常信息。
        // ... 省略代码 ...
    }

    public void execute(ForkJoinTask<?> task) {
        // 1. 提交新（并发）任务，无返回值，无法抛出异常信息。
        // ... 省略代码 ...
    }

    public ForkJoinTask<?> submit(Runnable task) {
        // 2. 提交新任务，无返回值，可以抛出异常信息，通过 ForkJoinTask 捕获异常。
        // ... 省略代码 ...
        return null;
    }

    public <T> ForkJoinTask<T> submit(Runnable task, T result) {
        // 3. 提交新任务，有（指定）返回值，可以抛出异常信息，通过 ForkJoinTask 获取结果及捕获异常。
        // ... 省略代码 ...
        return null;
    }

    public <T> ForkJoinTask<T> submit(Callable<T> task) {
        // 4. 提交新任务，有（执行）返回值，可以抛出异常信息，通过 ForkJoinTask 获取结果及捕获异常。
        // ... 省略代码 ...
        return null;
    }

    public <T> ForkJoinTask<T> submit(ForkJoinTask<T> task) {
        // 4. 提交新（并发）任务，有（执行）返回值，可以抛出异常信息，通过 ForkJoinTask 获取结果及捕获异常。
        // ... 省略代码 ...
        return null;
    }

    @Override
    public void shutdown() {
        /**
         * 有序关闭线程池，此方法会将线程池状态更新为 SHUTDOWN，此状态下的线程池：
         * 1）不再接收新任务，如果还继续往线程池中提交新任务，将会使用线程池的拒绝策略进行响应，默认的拒绝策略为 AbortPolicy（直接拒绝），直接抛出 RejectedExecutionException 拒绝执行异常，其他可选拒绝策略包括 DiscardPolicy（直接丢弃）、DiscardOldestPolicy（丢弃最老的）、CallerRunsPolicy（调用者执行）、自定义拒绝策略等；
         * 2）等待工作队列中的任务全部有序执行完毕后，进入 STOP 状态。
         */
    }

    @Override
    public List<Runnable> shutdownNow() {
        /**
         * 立即停止线程池，此方法会立即将线程池更新为 STOP，此状态下的线程池：
         * 1）不再接收新任务，同上；
         * 2）清空工作队列中的任务，返回给调用者；
         * 3）中断所有的 Worker 工作线程，当所有 Worker 工作线程都已经终止时，进入 TIDYING 状态。
         */
        return null;
    }

    @Override
    public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
        /**
         * （限时）等待线程池终止。
         * - 如果在等待时间内线程池完成终止，则返回 true，否则返回 false。
         */
        return false;
    }

    @Override
    public boolean isShutdown() {
        return !isRunning(ctl.get());
    }

    @Override
    public boolean isTerminated() {
        return runStateAtLeast(ctl.get(), TERMINATED);
    }

}
